package base

import kotlin.reflect.jvm.javaField
import kotlin.reflect.jvm.javaGetter

/**
 * Created by Darkness1m on 2017/6/7.
 */
//类引用
val c = MyClass::class//KClass类型
val c1 = Map::class.java//java的Class类型
val ref: A = B()
fun isOdd(x: Int) = x % 2 != 0
//重载一个
fun isOdd(s: String) = s == "brillig" || s == "slithy" || s == "tove"
fun <A,B,C> compose(f: (B) -> C, g: (A) -> B): (A) -> C{
    return { x -> f(g(x))}
}

//效果: base.compose(f,g) = f(g(*))
fun length(s: String) = s.length
fun main16(args: Array<String>) {
//    println(base.getRef::class.qualifiedName)//获取其精确类的类名
    val numbers = listOf(1,2,3)
    val strings = listOf("base.getA","slithy","base.getC")
    println(numbers.filter(::isOdd))//将方法的引用传递过去
    println(strings.filter(::isOdd))//将方法的引用传递过去//自动识别重载方法

    val oddLength = base.compose(::isOdd, ::length)
    val strings2 = listOf("base.getA","ab","abc")
    println(strings2.filter(oddLength))
}

//属性引用
var x = 1
//类引用
class RefA(val a: Int)
//扩展属性
val String.lastChar: Char
    get() = this[length - 1]

fun main17(args: Array<String>) {
    println(::x.get())//1
    ::x.set(2)//::base.getX 为 KProperty<Int>类型的属性对象
    //对于var而言则为 KMutableProperty<Int>对象//该对象拥有set()方法
    println(base.x)//2

    val strs = listOf("base.getA","bc","def")
    println(strs.map(String::length))//[1, 2, 3]

    //-------------------
    val prop = base.RefA::a
    println(prop.get(base.RefA(1)))//1

    println(String::lastChar.get("abc"))//base.getC
}

class ReflectClass(val p: Int){
    constructor() : this(1)
}

//构造函数引用
fun consRef(factory:() -> base.ReflectClass){//根据参数来确定引用哪个构造函数
    val x: base.ReflectClass = factory()//引用其无参构造函数
}

fun main(args: Array<String>) {
    val p = base.ReflectClass::p
    println(p.javaGetter)//获取对应于java类的get方法//public final int base.ReflectClass.getP()
    println(p.javaField)//private final int base.ReflectClass.p
    println(p.javaClass.kotlin)//获取对应于Java类的Kotlin类

    base.consRef(::ReflectClass)

    //引用特定对象的实例方法
    val numberRegex = "\\d+".toRegex()
    println(numberRegex.matches("28"))

    val isNumber = numberRegex::matches
    println(isNumber("28"))

    val ss = listOf("abc","123","2ad")
    println(ss.filter(numberRegex::matches))

}
